/**
 * Author: luoqi
 * Created Date: 2025-10-15 21:16:1
 * Last Modified: 2025-11-24 21:50:26
 * Modified By: luoqi at <**@****>
 * Copyright (c) 2025 <*****>
 * Description:
 */

#pragma once
#ifndef _CANPORT_H_
#define _CANPORT_H_

#include <cstdint>
#include <cstdlib>
#include <unistd.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <sys/socket.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <fcntl.h>

class CanPort {
public:
    using CanFrame = struct can_frame;
    using CanfdFrame = struct canfd_frame;

    enum CanType {
        CAN,
        CANFD
    };

    CanPort(const char *ifname, int bitrate = 1000000, CanType type = CANFD, int dbitrate = 5000000);
    ~CanPort();

    int open();
    int close();
    
    int send(uint16_t id, void *data, uint8_t sz);
    int recv(uint16_t &id, void *rbuf, uint8_t &sz, int timeout_ms);
        
    int send(CanFrame frame);
    int recv(CanFrame &frame, int timeout_ms);
    
    int send(CanfdFrame frame);
    int recv(CanfdFrame &frame, int timeout_ms);

private:
    int sock_{ -1 };
    struct sockaddr_can addr_;
    struct ifreq ifr_;
    CanType type_;
    const char *ifname_;
    int bitrate_ { 1000000 };
    int dbitrate_ { 5000000 };
};

#endif
